﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using snat.model;

namespace snat.algorithms.network {
    public class Statistics {
        public static List<BaseNode> NodeWithMostConnections {
            get {
                int max = NetworkModel.Instance.Nodes.Values.Max(e => e.EdgeCount);
                List<BaseNode> mostConnectedNodes = NetworkModel.Instance.Nodes.Values.Where<BaseNode>(e => e.EdgeCount == max).ToList<BaseNode>();
                return mostConnectedNodes;
            }
        }

        private static int? mostConnectedOut;
        public static int MostConnectedOut {
            get {
                if (mostConnectedOut.HasValue) return mostConnectedOut.Value;
                else {
                    if (MostConnectedOutWorker.HasValue) {
                        mostConnectedOut = MostConnectedOutWorker.Value;
                        return (int)mostConnectedOut;
                    }
                    return -1;
                }
            }
        }
        private static int? MostConnectedOutWorker {
            get {
                int maxDegree = 0;
                int? influential = null;
                BaseNode temp;
                foreach (KeyValuePair<int, BaseNode> n in NetworkModel.Instance.Nodes) {
                    temp = n.Value;
                    if (temp.OutEdgeCount > maxDegree) {
                        influential = temp.ID;
                        maxDegree = temp.OutEdgeCount;
                    }
                }
                return influential;
            }
        }
        public static int? LargestDegreeOut {
            get {
                try {
                    if (MostConnectedOut != -1) return NetworkModel.Instance.Nodes[MostConnectedOut].OutEdgeCount;
                } catch (KeyNotFoundException ex) {
                    // Throw Ste Error
                }
                return null;
            }
        }

        private static int? mostConnectedIn;
        public static int MostConnectedIn {
            get {
                if (mostConnectedIn.HasValue) return mostConnectedIn.Value;
                else {
                    if (MostConnectedInWorker.HasValue) {
                        mostConnectedIn = MostConnectedInWorker.Value;
                        return (int)mostConnectedIn;
                    }
                    return -1;
                }
            }
        }
        private static int? MostConnectedInWorker {
            get {
                int maxDegree = 0;
                int? influential = null;
                BaseNode temp;
                foreach (KeyValuePair<int, BaseNode> n in NetworkModel.Instance.Nodes) {
                    temp = n.Value;
                    if (temp.InEdgeCount > maxDegree) {
                        influential = temp.ID;
                        maxDegree = temp.InEdgeCount;
                    }
                }
                return influential;
            }
        }
        public static int? LargestDegreeIn {
            get {
                try {
                    if (MostConnectedIn != -1) return NetworkModel.Instance.Nodes[MostConnectedIn].InEdgeCount;
                }
                catch (KeyNotFoundException ex) {
                    // Throw Ste Error
                }
                return null;
            }
        }

    }
}
